<script setup>
import { ref, computed } from 'vue'
import { useShopStore } from '../stores/05.actions(组合式)'
import { storeToRefs } from 'pinia'

// 获取store实例
const shopStore = useShopStore()

// 使用storeToRefs保持响应性
const { products, cart, user, orderHistory } = storeToRefs(shopStore)

// 登录表单
const loginForm = ref({
  username: '',
  password: ''
})

// 登录状态消息
const loginMessage = ref('')

// 添加到购物车的商品ID
const selectedProductId = ref(1)

// 添加到购物车的数量
const quantity = ref(1)

// 操作结果消息
const actionMessage = ref('')

// 是否显示结果消息
const showMessage = ref(false)

// 消息类型（成功/失败）
const messageType = ref('success')

// 处理登录
async function handleLogin() {
  if (!loginForm.value.username || !loginForm.value.password) {
    showActionMessage('用户名和密码不能为空', 'error')
    return
  }
  
  try {
    const result = await shopStore.login(loginForm.value.username, loginForm.value.password)
    showActionMessage(result.message, result.success ? 'success' : 'error')
    
    if (result.success) {
      loginForm.value = { username: '', password: '' }
    }
  } catch (error) {
    showActionMessage(error.message, 'error')
  }
}

// 处理登出
function handleLogout() {
  const result = shopStore.logout()
  showActionMessage(result.message, 'success')
}

// 添加商品到购物车
function addProductToCart() {
  try {
    const result = shopStore.addToCart(Number(selectedProductId.value), Number(quantity.value))
    showActionMessage(result.message, 'success')
  } catch (error) {
    showActionMessage(error.message, 'error')
  }
}

// 从购物车移除商品
function removeProductFromCart(productId) {
  try {
    const result = shopStore.removeFromCart(productId)
    showActionMessage(result.message, 'success')
  } catch (error) {
    showActionMessage(error.message, 'error')
  }
}

// 处理结账
async function handleCheckout() {
  try {
    const result = await shopStore.checkout()
    showActionMessage(result.message, result.success ? 'success' : 'error')
  } catch (error) {
    showActionMessage(error.message, 'error')
  }
}

// 显示操作结果消息
function showActionMessage(message, type = 'success') {
  actionMessage.value = message
  messageType.value = type
  showMessage.value = true
  
  // 3秒后自动隐藏消息
  setTimeout(() => {
    showMessage.value = false
  }, 3000)
}
</script>

<template>
  <div class="tutorial-container">
    <header>
      <h1>05.actions(组合式)</h1>
      <p class="subtitle">学习如何在组合式API中定义和使用actions</p>
      
      <nav class="tutorial-nav">
        <router-link to="/01" class="nav-link">01.认识pinia</router-link>
        <router-link to="/02" class="nav-link">02.定义store(选项式)</router-link>
        <router-link to="/02c" class="nav-link">02.定义store(组合式)</router-link>
        <router-link to="/03" class="nav-link">03.state(选项式)</router-link>
        <router-link to="/03c" class="nav-link">03.state(组合式)</router-link>
        <router-link to="/04" class="nav-link">04.getters(选项式)</router-link>
        <router-link to="/04c" class="nav-link">04.getters(组合式)</router-link>
        <router-link to="/05" class="nav-link">05.actions(选项式)</router-link>
        <router-link to="/05c" class="nav-link">05.actions(组合式)</router-link>
      </nav>
    </header>

    <main>
      <section class="intro">
        <h2>什么是 Actions?</h2>
        <p>Actions 相当于组件中的 methods。它们可以包含任意异步或同步操作，可以调用其他 actions，可以通过 this 访问整个 store 实例。</p>
        
        <div class="code-example">
          <pre><code>// 定义一个带有actions的store
export const useStore = defineStore('storeId', {
  state: () => ({
    count: 0,
    userData: null
  }),
  actions: {
    // 同步action
    increment() {
      this.count++
    },
    // 异步action
    async fetchUserData() {
      const response = await fetch('/api/user')
      this.userData = await response.json()
    },
    // 调用其他action的action
    async initUser() {
      await this.fetchUserData()
      this.increment()
    }
  }
})</code></pre>
        </div>
      </section>

      <div class="demo-section">
        <div class="shop-demo">
          <h2>购物系统示例</h2>
          
          <!-- 操作结果消息 -->
          <div v-if="showMessage" :class="['message', messageType]">
            {{ actionMessage }}
          </div>
          
          <!-- 用户登录部分 -->
          <div class="card">
            <h3>用户管理</h3>
            
            <div v-if="!shopStore.isAuthenticated" class="login-form">
              <div class="form-group">
                <label>用户名</label>
                <input v-model="loginForm.username" type="text" placeholder="请输入用户名" />
              </div>
              
              <div class="form-group">
                <label>密码</label>
                <input v-model="loginForm.password" type="password" placeholder="请输入密码" />
              </div>
              
              <button @click="handleLogin" class="btn primary">登录</button>
            </div>
            
            <div v-else class="user-info">
              <h4>欢迎回来，{{ user.name }}</h4>
              <p>积分: {{ user.points }}</p>
              <button @click="handleLogout" class="btn secondary">登出</button>
            </div>
          </div>
          
          <!-- 商品列表 -->
          <div class="card">
            <h3>商品列表</h3>
            
            <div class="products-list">
              <div v-for="product in products" :key="product.id" class="product-item">
                <div class="product-info">
                  <h4>{{ product.name }}</h4>
                  <p>价格: ¥{{ product.price }}</p>
                  <p>库存: {{ product.inventory }}</p>
                </div>
                
                <div class="product-actions" v-if="product.inventory > 0">
                  <button 
                    @click="() => { selectedProductId = product.id; quantity = 1; addProductToCart(); }" 
                    class="btn primary small"
                  >
                    加入购物车
                  </button>
                </div>
                <div v-else class="product-actions">
                  <span class="out-of-stock">已售罄</span>
                </div>
              </div>
            </div>
          </div>
          
          <!-- 购物车 -->
          <div class="card">
            <h3>购物车 ({{ shopStore.cartItemCount }})</h3>
            
            <div v-if="cart.length === 0" class="empty-cart">
              <p>购物车为空</p>
            </div>
            
            <div v-else>
              <div class="cart-items">
                <div v-for="item in cart" :key="item.productId" class="cart-item">
                  <div class="item-info">
                    <h4>{{ products.find(p => p.id === item.productId)?.name }}</h4>
                    <p>数量: {{ item.quantity }}</p>
                    <p>单价: ¥{{ products.find(p => p.id === item.productId)?.price }}</p>
                    <p>小计: ¥{{ (products.find(p => p.id === item.productId)?.price || 0) * item.quantity }}</p>
                  </div>
                  
                  <div class="item-actions">
                    <button @click="() => removeProductFromCart(item.productId)" class="btn danger small">移除</button>
                  </div>
                </div>
              </div>
              
              <div class="cart-summary">
                <p class="total">总计: ¥{{ shopStore.cartTotalPrice }}</p>
                <div class="cart-actions">
                  <button @click="shopStore.clearCart" class="btn secondary">清空购物车</button>
                  <button @click="handleCheckout" class="btn primary" :disabled="!shopStore.isAuthenticated">
                    {{ shopStore.isAuthenticated ? '结账' : '请先登录' }}
                  </button>
                </div>
              </div>
            </div>
          </div>
          
          <!-- 订单历史 -->
          <div v-if="shopStore.isAuthenticated && orderHistory.length > 0" class="card">
            <h3>订单历史</h3>
            
            <div class="order-history">
              <div v-for="order in orderHistory" :key="order.id" class="order-item">
                <div class="order-header">
                  <h4>订单 #{{ order.id }}</h4>
                  <p>日期: {{ new Date(order.date).toLocaleString() }}</p>
                  <p>状态: {{ order.status }}</p>
                </div>
                
                <div class="order-details">
                  <p>总金额: ¥{{ order.totalAmount }}</p>
                  <p>商品数量: {{ order.items.reduce((sum, item) => sum + item.quantity, 0) }}</p>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      
      <section class="explanation">
        <h2>组合式API中使用Actions</h2>
        
        <div class="subsection">
          <h3>1. 直接调用Actions</h3>
          <p>在组合式API中，你可以直接从store实例调用actions：</p>
          <div class="code-example">
            <pre><code>import { useStore } from './store'

// 在组件中
export default {
  setup() {
    const store = useStore()
    
    // 直接调用action
    store.increment()
    
    // 调用异步action
    store.fetchUserData()
    
    return {
      // 将action暴露给模板
      increment: () => store.increment()
    }
  }
}</code></pre>
          </div>
        </div>
        
        <div class="subsection">
          <h3>2. 解构Actions</h3>
          <p>与getters不同，actions可以直接解构而不会失去响应性：</p>
          <div class="code-example">
            <pre><code>import { useStore } from './store'

export default {
  setup() {
    const store = useStore()
    
    // 直接解构actions
    const { increment, fetchUserData } = store
    
    // 使用解构的actions
    increment()
    fetchUserData()
    
    return {
      increment,
      fetchUserData
    }
  }
}</code></pre>
          </div>
        </div>
        
        <div class="subsection">
          <h3>3. 异步Actions</h3>
          <p>Pinia支持异步actions，你可以使用async/await语法：</p>
          <div class="code-example">
            <pre><code>import { useStore } from './store'

export default {
  setup() {
    const store = useStore()
    
    // 调用异步action
    async function loadData() {
      try {
        await store.fetchUserData()
        console.log('数据加载成功')
      } catch (error) {
        console.error('数据加载失败', error)
      }
    }
    
    return {
      loadData
    }
  }
}</code></pre>
          </div>
        </div>
        
        <div class="subsection">
          <h3>4. 订阅Actions</h3>
          <p>你可以使用<code>$onAction</code>方法订阅store中的actions：</p>
          <div class="code-example">
            <pre><code>import { useStore } from './store'

export default {
  setup() {
    const store = useStore()
    
    // 订阅actions
    store.$onAction(({
      name, // action名称
      store, // store实例
      args, // 传递给action的参数数组
      after, // action返回或解决后的钩子
      onError // action抛出或拒绝的钩子
    }) => {
      console.log(`Action ${name} 开始执行，参数:`, args)
      
      // action成功完成后执行
      after((result) => {
        console.log(`Action ${name} 成功完成，结果:`, result)
      })
      
      // action出错时执行
      onError((error) => {
        console.error(`Action ${name} 执行失败:`, error)
      })
    })
    
    return {
      store
    }
  }
}</code></pre>
          </div>
        </div>
      </section>
    </main>
  </div>
</template>

<style scoped>
.tutorial-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

header {
  margin-bottom: 30px;
  border-bottom: 1px solid #eee;
  padding-bottom: 20px;
}

h1 {
  font-size: 2.5rem;
  margin-bottom: 10px;
}

.subtitle {
  font-size: 1.2rem;
  color: #666;
  margin-bottom: 20px;
}

.tutorial-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 20px;
}

.nav-link {
  padding: 8px 15px;
  background-color: #f5f5f5;
  border-radius: 4px;
  text-decoration: none;
  color: #333;
  transition: background-color 0.2s;
}

.nav-link:hover {
  background-color: #e0e0e0;
}

.intro {
  margin-bottom: 40px;
}

.code-example {
  background-color: #f8f8f8;
  border-radius: 6px;
  padding: 15px;
  margin: 15px 0;
  overflow-x: auto;
}

pre {
  margin: 0;
}

code {
  font-family: 'Courier New', monospace;
  font-size: 0.9rem;
}

.demo-section {
  margin-bottom: 40px;
}

.card {
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  padding: 20px;
  margin-bottom: 20px;
}

.form-group {
  margin-bottom: 15px;
}

label {
  display: block;
  margin-bottom: 5px;
  font-weight: 500;
}

input {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 1rem;
}

.btn {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 1rem;
  transition: background-color 0.2s;
}

.btn.primary {
  background-color: #4CAF50;
  color: white;
}

.btn.primary:hover {
  background-color: #3e8e41;
}

.btn.secondary {
  background-color: #f1f1f1;
  color: #333;
}

.btn.secondary:hover {
  background-color: #e0e0e0;
}

.btn.danger {
  background-color: #f44336;
  color: white;
}

.btn.danger:hover {
  background-color: #d32f2f;
}

.btn.small {
  padding: 4px 8px;
  font-size: 0.9rem;
}

.btn:disabled {
  background-color: #cccccc;
  cursor: not-allowed;
}

.message {
  padding: 10px 15px;
  border-radius: 4px;
  margin-bottom: 20px;
}

.message.success {
  background-color: #dff0d8;
  color: #3c763d;
  border: 1px solid #d6e9c6;
}

.message.error {
  background-color: #f2dede;
  color: #a94442;
  border: 1px solid #ebccd1;
}

.products-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 20px;
}

.product-item {
  border: 1px solid #eee;
  border-radius: 6px;
  padding: 15px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.product-info {
  margin-bottom: 15px;
}

.product-actions {
  display: flex;
  justify-content: flex-end;
}

.out-of-stock {
  color: #f44336;
  font-style: italic;
}

.cart-items {
  margin-bottom: 20px;
}

.cart-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid #eee;
}

.cart-summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 20px;
}

.total {
  font-size: 1.2rem;
  font-weight: bold;
}

.cart-actions {
  display: flex;
  gap: 10px;
}

.empty-cart {
  text-align: center;
  padding: 20px;
  color: #666;
}

.order-history {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.order-item {
  border: 1px solid #eee;
  border-radius: 6px;
  padding: 15px;
}

.order-header {
  margin-bottom: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid #eee;
}

.explanation {
  margin-top: 40px;
}

.subsection {
  margin-bottom: 30px;
}
</style>
